// SkinableGUIButton.cpp : implementation file
//

#include "stdafx.h"
#include "SkinableGUIButton.h"

using namespace SkinableGUI;
// CSkinableGUIButton

IMPLEMENT_DYNAMIC(CSkinableGUIButton, CButton)
CSkinableGUIButton::CSkinableGUIButton(SkinButton * pSkinButton) :
m_pSkinButton(pSkinButton)
, m_hBkBrush(NULL)
{

}

CSkinableGUIButton::~CSkinableGUIButton()
{
}


BEGIN_MESSAGE_MAP(CSkinableGUIButton, CButton)
	ON_WM_CREATE()
	ON_WM_CTLCOLOR_REFLECT()
	ON_WM_DESTROY()
	ON_WM_DRAWITEM()
	ON_WM_TIMER()
END_MESSAGE_MAP()



// SkinableGUIButton message handlers



int SkinableGUI::CSkinableGUIButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CButton::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (m_pSkinButton == NULL)
		return -1;

	if (m_pSkinButton->ButtonTextSet)
		SetWindowText(m_pSkinButton->ButtonText);

	if (m_pSkinButton->BackgroundImageSet)
		m_BackgroundImage.Load(&m_pSkinButton->BackgroundImage);

	SetTimer(IDT_SKINABLE_BUTTON,
		150, NULL);

	return 0;
}

HBRUSH SkinableGUI::CSkinableGUIButton::CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/)
{
	if (m_pSkinButton->BackgroundColorSet)
	{
		if (m_hBkBrush == NULL)
			m_hBkBrush = ::CreateSolidBrush(m_pSkinButton->BackgroundColor.ToColor());

		return m_hBkBrush;
	}

	return NULL;
}

void SkinableGUI::CSkinableGUIButton::OnDestroy()
{
	CButton::OnDestroy();

	if (m_hBkBrush != NULL)
		::DeleteObject(m_hBkBrush);
}

BOOL SkinableGUI::CSkinableGUIButton::PreCreateWindow(CREATESTRUCT& cs)
{
	if (m_pSkinButton != NULL && m_pSkinButton->BackgroundImageSet)
	{
		cs.style |= BS_OWNERDRAW;
	}

	return CButton::PreCreateWindow(cs);
}

void SkinableGUI::CSkinableGUIButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	//	DrawItem(lpDrawItemStruct);
}

void SkinableGUI::CSkinableGUIButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

	CRect rcItem(lpDrawItemStruct->rcItem);

	UINT uState = DFCS_BUTTONPUSH;

	if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)
	{
		uState |= DFCS_PUSHED;
	}

#ifndef _WIN32_WCE
	if ((lpDrawItemStruct->itemState & ODS_FOCUS) == ODS_FOCUS)
	{
		uState |= DFCS_HOT;
	}
#endif

	if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED)
	{
		uState |= DFCS_INACTIVE;
	}

	pDC->DrawFrameControl(rcItem, 
		DFC_BUTTON,
		uState);

	rcItem.DeflateRect(3,3);

	if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)
	{
		rcItem.DeflateRect(1,1);
	}

	if (m_pSkinButton->BackgroundColorSet)
	{
		pDC->FillSolidRect(&rcItem, 
			m_pSkinButton->BackgroundColor.ToColor());
	}

	rcItem.DeflateRect(1,1);

	if (m_pSkinButton->BackgroundImageSet)
	{
		DrawButtonImage(pDC,
			&m_BackgroundImage,
			rcItem);
	}
	else if (m_pSkinButton->ButtonTextSet)
	{
		::DrawText(lpDrawItemStruct->hDC, 
			m_pSkinButton->ButtonText, 
			m_pSkinButton->ButtonText.GetLength(), 
			&rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	}
}

void SkinableGUI::CSkinableGUIButton::OnTimer(UINT_PTR nIDEvent)
{
	static int frame_count = 0;

	if (m_pSkinButton->BackgroundImageSet)
	{
		if (m_BackgroundImage.GetNumFrames() == 1)
			return;

		CDC * pDC = GetDC();

		CRect rcClient;

		GetClientRect(&rcClient);

		if (frame_count >= m_BackgroundImage.GetNumFrames())
		{
			frame_count = 0;
		}

		rcClient.DeflateRect(3,3);

		if (GetState() & 0x0004)
		{
			rcClient.DeflateRect(1,1);
		}

		rcClient.DeflateRect(1,1);

		DrawButtonImage(pDC,
			&m_BackgroundImage,
			rcClient,
			frame_count);

		ReleaseDC(pDC);

		frame_count++;
	}
}

void SkinableGUI::CSkinableGUIButton::DrawButtonImage(CDC * pDC,
	CSkinableGUIImage * pImage , const CRect & rcItem, UINT nFrame)
{
	CSize size = pImage->GetImageSize();

	CRect rcImage;

	if (size.cx > rcItem.Width() || size.cy > rcItem.Height())
	{
		int DisplayHeight = (int)(size.cy * ((double)rcItem.Width() / (double)size.cx));
		int DisplayWidth = (int)(size.cx * ((double)rcItem.Height() / (double)size.cy));

		if (DisplayWidth < rcItem.Width())
		{
			rcImage.left = rcItem.left + (rcItem.Width() - DisplayWidth)/2;
			rcImage.top = rcItem.top;
			rcImage.right = rcItem.left + DisplayWidth;
			rcImage.bottom = rcItem.bottom;
		}
		else
		{
			rcImage.left = rcItem.left;
			rcImage.top = rcItem.top + (rcItem.Height() - DisplayHeight)/2;
			rcImage.right = rcItem.right;
			rcImage.bottom = rcImage.top + DisplayHeight;
		}
	}
	else
	{
		rcImage.left = rcItem.left + (rcItem.Width() - size.cx)/2;
		rcImage.top = rcItem.top + (rcItem.Height() - size.cy)/2;
		rcImage.right = rcItem.left + size.cx;
		rcImage.bottom = rcImage.top + size.cy;
	}

	pImage->BltFrame(nFrame, pDC,
		&rcImage);
}
